<?php 
/* 
Plugin Name: WPJAM TOC
Plugin URI: http://wpjam.net/item/toc/
Version: 2.0
Author: denishua
Description: WordPress 文章目录插件	
Author URI: http://fairyfish.net/
Donate link: http://fairyfish.net/donate/
*/

add_action('init','toc_init');
function toc_init(){
	wp_enqueue_script("jquery");
}
add_action('wp_head','toc_head');
function toc_head(){
?>
<script type="text/javascript">
jQuery('#toc span').live('click',function(){
	if(jQuery('#toc span').html() == '[显示]'){
    	jQuery('#toc span').html('[隐藏]');
    }else{
    	jQuery('#toc span').html('[显示]');
    }
    jQuery('#toc #ul_1').toggle();
});
</script>
<style type="text/css">
#toc {
	float:right;
	max-width:200px;
	padding:6px;
	margin:0 0 20px 20px;
	border:1px solid #EDF3DE;
	background:white;
	-moz-border-radius:6px;
	-webkit-border-radius:6px;
	border-radius:6px;
}
#toc ul{
	padding-bottom:0;
}
#toc strong {
	border-bottom:1px solid #EDF3DE;
	display:block;
	font-size:16px;
	padding:0 4px;
}
#toc span {
	display:block;
	margin:4px;
    cursor:pointer;
}
#toc small {
	float: right;
}
</style>
<?php
}

function toc_replace_heading($content) {
	global $toc_count;
	global $toc;
	$toc_count ++;

	$toc[] = array('text' => trim(strip_tags($content[3])), 'depth' => $content[1], 'count' => $toc_count);

	return "<h$content[1] $content[2]><a name=\"toc-$toc_count\"></a>$content[3]</h$content[1]>";
}

add_filter('the_content', 'the_content_toc', 1);

function the_content_toc($content) {
	if(!is_single()) 
		return $content;

	$toc_depth = get_post_meta($post->ID,'toc_depth',true);
	if(!$toc_depth) $toc_depth = 6;

	$regex = '#<h([1-'.$toc_depth.'])(.*?)>(.*?)</h\1>#';	
	$content = preg_replace_callback(
		$regex,
		'toc_replace_heading',
		$content
	);

	if(strpos($content, '[toc]') !== false) return $content;
		
	$content = toc_index() . $content;
	
	return($content);
}

function toc_index(){
	global $toc_count;	
	global $toc;
	global $post;

	$toc_hidden = get_post_meta($post->ID,'toc_hidden',true);
	if($toc_hidden) 
		return;

	if($toc_count){
		$index = "\n<div id=\"toc\"><strong>文章目录</strong>";
		$index .= "<span>[隐藏]</span>";
		$index .= '<ul id="ul_1">';
		foreach($toc as $toc_item){
			if($prev){
				if($toc_item['depth'] == $prev){
					$index .= '</li>';
				}elseif($toc_item['depth'] > $prev){
					$index .= '<ul>';
				}else{
					$index .= "</li>\n</ul>\n</li>";
				}
			}
			$index .= "<li><a href=\"#toc-$toc_item[count]\">$toc_item[text]</a>";
			$prev = $toc_item['depth'];
		}
		$index .= "</li>\n</ul>\n";	
		
		$index .= "</div>\n";

		return $index;
	}
}

add_shortcode('toc', 'toc_shortcode_handler');
function toc_shortcode_handler($atts, $content='') {
	return toc_index();
}

add_action( 'add_meta_boxes', 'toc_add_custom_box' );

// backwards compatible (before WP 3.0)
// add_action( 'admin_init', 'toc_add_custom_box', 1 );
function toc_add_custom_box() {
	add_meta_box( 
		'toc_setting',
		'文章目录设置',
		'toc_inner_custom_box',
		'post' 
	);
}

function toc_inner_custom_box( $post ) {
	wp_nonce_field( plugin_basename( __FILE__ ), 'toc_setting' );
	$toc_hidden = get_post_meta($post->ID,'toc_hidden',true);
	if($toc_hidden) $toc_hidden_checked = 'checked';

	$toc_depth = get_post_meta($post->ID,'toc_depth',true);
	if(!$toc_depth) $toc_depth = 0;
?>
	<p>
		<label for="toc_hidden">是否隐藏文章目录：</label>
		<input type="checkbox" id="toc_hidden" name="toc_hidden" value="1" <?php echo $toc_hidden_checked; ?> />
	</p>
	<p>
		<label for="toc_depth">显示到第几级目录：</label>
		<select id="toc_depth" name="toc_depth" >
			<option value="0" <?php if($toc_depth == 0) echo "selected"; ?>>所有</option>
			<?php for($i=2;$i<=6;$i++) {
				$selected = '';
				if($i == $toc_depth ) $selected = 'selected';
				echo '<option value="'.$i.'" '.$selected.' >H'.$i.'</option>';
			} ?>
		</select>
	</p>
<?php 
}

add_action( 'save_post', 'toc_save_postdata' );
function toc_save_postdata( $post_id ) {
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
		return;

	if ( !wp_verify_nonce( $_POST['toc_setting'], plugin_basename( __FILE__ ) ) ) 
		return;

	if ( !current_user_can( 'edit_post', $post_id ) ) 
		return;

	if($_POST['toc_hidden'] || get_post_meta($post_id, 'toc_hidden',true))
		update_post_meta($post_id, 'toc_hidden', $_POST['toc_hidden']);

	if($_POST['toc_depth'] || get_post_meta($post_id, 'toc_depth',true))
		update_post_meta($post_id, 'toc_depth', $_POST['toc_depth']);

}
